package com.atguigu.springcloud.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.atguigu.springcloud.entity.CommonResult;
import com.atguigu.springcloud.entity.Payment;
import com.atguigu.springcloud.service.ConsumerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.validation.constraints.Null;

/**
 * @USER: dayu
 * @DATE: 2020/4/16
 * @DESCRIPTION:
 */
@RestController
@Slf4j
public class ConsumerController {

    @Value("${nacos-serever.server-url}")
    private String LOAD_SERVER;

    @Resource
    RestTemplate restTemplate;

    @GetMapping("/consumer/paymentSQL/{id}")
//    @SentinelResource(value = "fallback")
//    @SentinelResource(value = "fallback",fallback = "handlerFallback")// 兜底异常处理
//    @SentinelResource(value = "fallback",blockHandler = "blockHandlerPayment")    //流控处理
    @SentinelResource(value = "fallback",
            fallback = "handlerFallback",
            blockHandler = "blockHandlerPayment",
            exceptionsToIgnore = {IllegalArgumentException.class})//当两个限制同时使用的情况下，如果不限流-兜底处理，如果达到限流阈值，走blockHandler方法.
    //exceptionsToIgnore表示忽略指定的异常，如果程序跑出指定异常的话，不再有fallback兜底方法
    public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id) {
        CommonResult<Payment> result = restTemplate.getForObject(LOAD_SERVER + "/paymentSQL/" + id, CommonResult.class);

        if (id == 4) {
            throw new IllegalArgumentException("IllegalArgumentException,非法参数异常");
        } else if (result.getData() == null) {
            throw new NullPointerException("NullPointerException,该ID没有对应的订单，空指针异常");
        }
        return result;
    }

    public CommonResult handlerFallback(@PathVariable("id") Long id, Throwable e) {
        Payment payment = new Payment(id, "null");
        return new CommonResult(444, "兜底异常处理：" + e.getMessage(), payment);
    }


    public CommonResult blockHandlerPayment(@PathVariable Long id, BlockException exception) {
        Payment payment = new Payment(id, "null");
        return new CommonResult(445, "blockHandlerPayment 异常处理：" + exception.getClass().getCanonicalName(), payment);
    }


    //=========open-feign============
    @Resource
    ConsumerService consumerService;

    @GetMapping("/consumer/feign/paymentSQL/{id}")
    public CommonResult<Payment> paymentSQL2(@PathVariable("id") Long id) {
    return consumerService.paymentSQL(id);
    }
}
